#ifndef _DOF_
#define _DOF_

#include "vl/VLd.h"

#define DOF_MAGIC_NO 0
//static int dofCount=DOF_MAGIC_NO;

class BodyLink;
class Transformation;
class Joint;

class Dof{
protected:
	char *mName;
	int mID;	// universally unique id
	int mModelID;	// unique to dof in model

	double mVal;	// value of the joint angle
	double mLastVal;
	double mMin;	// min value allowed
	double mMax;	// max value allowed
	double mInitVal;
	double mVelocity;

	Transformation *mTrans;	// transformation associated with
	Joint *mJoint;	// joint to which it belongs

	bool mDerivFlag;	// true when at least one trans has been differentiated.
	bool mVariable;		// true when it is a variable and included int he model

	void init(double _v, char * _name, double _min, double Max);
	static int mDofCount;
public:
	Dof();
	Dof(double val);
	Dof(double val, double min, double max);
	Dof(double val, char *name);
	Dof(double val, char *name, double min, double max);
	
	~Dof(){
		delete mName;
	}
	void switchBetweenLastAndCurrentValue();
	// some inline helper functions
	inline char* getName(){return mName;}
	inline void setValue(double v){mLastVal = mVal; mVal=v;}	// set the value as v
	inline double getValue(){return mVal;}	// get the value
	inline double getLastValue() {return mLastVal;}
	inline double getMin(){return mMin;}
	inline double getMax(){return mMax;}
	inline double getInitValue() {return mInitVal;}
	inline void setMin(double _min){mMin=_min;}
	inline void setMax(double _max){mMax=_max;}
	inline int getModelID(){return mModelID;}
	inline void setModelID(int _id){mModelID=_id;}
	inline int getID(){return mID;}
	inline bool getDerivFlag(){return mDerivFlag;}
	inline void setDerivFlag(bool _flag){mDerivFlag=_flag;}
	inline bool isVariable(){return mVariable;}
	inline void setVariable(){mVariable=true;}
	inline void setTrans(Transformation *_t){mTrans=_t;}
	inline Transformation* getTrans(){return mTrans;}
	inline void setJoint(Joint *_j){mJoint=_j;}
	inline Joint *getJoint(){return mJoint;}
	inline double getVelocity() {return mVelocity;}
	inline void setVelocity(double v) {mVelocity = v;}
};

#endif
